#include "stdafx.h"
#include <stdio.h>
#include "PacketCollector.h"

#define D_SEM_TIMOUT (1000 * 1000)
#define D_EVENT_TIMOUT (1000 * 2)


struct PacketCtrl
{
	HANDLE sem_obj;
	HANDLE event_obj;
	HANDLE snd_event;

	PacketReaderHandle readerHandle;
	PacketWriterHandle writerHandle;
};

static PacketCtrl gPacketCtrl;
static PacketCtrl *pPackCtrl;

static void sem_init(PacketCtrl *pCtrl)
{
	pCtrl->sem_obj = CreateSemaphore(NULL, 1, 100, NULL);
}
static void sem_wait(PacketCtrl *pCtrl)
{
	int ret = WaitForSingleObject(pCtrl->sem_obj, D_SEM_TIMOUT);
	if (ret == WAIT_OBJECT_0)
		return;

	printf("sem_wait error: ret=%x\n", ret);
}

static void sem_sig(PacketCtrl *pCtrl)
{
	int ret = ReleaseSemaphore(pCtrl->sem_obj, 1, NULL);
	if (ret != 0)
		return;

	printf("sem_sig error: ret=%x\n", ret);
}
static void sem_close(PacketCtrl *pCtrl)
{
	CloseHandle(pCtrl->sem_obj);
	pCtrl->sem_obj = NULL;
}


static void event_init(PacketCtrl *pCtrl)
{
	pCtrl->event_obj = CreateEvent(NULL, FALSE, TRUE, NULL);
}
static void event_wait(PacketCtrl *pCtrl)
{
	int ret = WaitForSingleObject(pCtrl->event_obj, D_SEM_TIMOUT);
	if (ret == WAIT_OBJECT_0)
		return;

	printf("event_wait error: ret=%x\n", ret);
}
static void event_reset(PacketCtrl *pCtrl)
{
	int ret = ResetEvent(pCtrl->event_obj);
}

static void event_sig(PacketCtrl *pCtrl)
{
	int ret = SetEvent(pCtrl->event_obj);
}
static void event_close(PacketCtrl *pCtrl)
{
	CloseHandle(pCtrl->event_obj);
	pCtrl->event_obj = NULL;
}

static void send_event_init(PacketCtrl *pCtrl)
{
	pCtrl->snd_event = CreateEvent(NULL, FALSE, FALSE, NULL); 
}
static void send_event_wait(PacketCtrl *pCtrl)
{
	int ret = WaitForSingleObject(pCtrl->snd_event, D_EVENT_TIMOUT);
	if (ret == WAIT_OBJECT_0)
		return;

	printf("event_wait error: ret=%x\n", ret);
}
static void send_event_reset(PacketCtrl *pCtrl)
{
	int ret = ResetEvent(pCtrl->snd_event);
}

static void send_event_sig(PacketCtrl *pCtrl)
{
	int ret = SetEvent(pCtrl->snd_event);
}
static void send_event_close(PacketCtrl *pCtrl)
{
	CloseHandle(pCtrl->event_obj);
	pCtrl->event_obj = NULL;
}

void PacketCollectInit()
{
	memset(&gPacketCtrl, 0, sizeof(gPacketCtrl));
	pPackCtrl = &gPacketCtrl;
	sem_init(pPackCtrl);
	event_init(pPackCtrl);
	send_event_init(pPackCtrl);
}

void PacketCollectClose()
{
	sem_close(pPackCtrl);
	event_close(pPackCtrl);
	send_event_close(pPackCtrl);
	pPackCtrl = NULL;
}
int ReceivePacketSet(PacketReaderHandle handle)
{
	sem_wait(pPackCtrl);
	pPackCtrl->readerHandle = handle;
	pPackCtrl->writerHandle = NULL;
	event_reset(pPackCtrl);

	return 0;
}

int ReceivePacketGet(PacketReaderHandle *handle)
{
	*handle = pPackCtrl->readerHandle;
	if (*handle == NULL)
		return -1;
	else
		pPackCtrl->readerHandle = NULL;
		return 1;
}

int SendPacketSet(PacketWriterHandle handle)
{
	pPackCtrl->writerHandle = handle;
	event_sig(pPackCtrl);
	send_event_reset(pPackCtrl);
	send_event_wait(pPackCtrl);
	return 0;
}

int SendPacketGet(PacketWriterHandle *handle)
{
	if (pPackCtrl->writerHandle == NULL)
		event_wait(pPackCtrl);
	*handle = pPackCtrl->writerHandle;
	if (*handle == NULL)
	{
		return -1;
	}
	else
	{
		pPackCtrl->writerHandle = NULL;
		return 0;
	}
}

int SendPacketFree()
{
	send_event_sig(pPackCtrl);
	sem_sig(pPackCtrl);
	return 0;
}